const express = require('express');
const crypto = require('crypto');
const deployService = require('../services/deployService');
const historyService = require('../services/historyService');
const config = require('../config/default.json');
const logger = require('../utils/logger');

const router = express.Router();

// 验证Webhook签名（支持GitHub和Gitea格式）
function verifySignature(payload, signature, secret, webhookType = 'auto') {
  if (!secret) return true; // 如果没有设置密钥，跳过验证
  if (!signature) return false; // 如果没有签名，返回false
  
  try {
    const hmac = crypto.createHmac('sha256', secret);
    hmac.update(payload);
    
    // GitHub格式: sha256=<hex>
    if (webhookType === 'github' || (webhookType === 'auto' && signature.startsWith('sha256='))) {
      const calculatedSignature = 'sha256=' + hmac.digest('hex');
      return crypto.timingSafeEqual(
        Buffer.from(signature),
        Buffer.from(calculatedSignature)
      );
    }
    
    // Gitea/Gogs格式: 直接是hex字符串
    if (webhookType === 'gitea' || webhookType === 'gogs' || webhookType === 'auto') {
      const calculatedSignature = hmac.digest('hex');
      return crypto.timingSafeEqual(
        Buffer.from(signature),
        Buffer.from(calculatedSignature)
      );
    }
    
    return false;
  } catch (error) {
    logger.error('签名验证错误', { error: error.message, webhookType, signature });
    return false;
  }
}

// 检测Webhook类型
function detectWebhookType(headers) {
  if (headers['x-gitea-event'] || headers['x-gitea-delivery']) {
    return 'gitea';
  }
  if (headers['x-github-event'] || headers['x-hub-signature-256']) {
    return 'github';
  }
  if (headers['x-gogs-event'] || headers['x-gogs-delivery']) {
    return 'gogs';
  }
  return 'unknown';
}

// 处理Webhook请求
router.post('/', async (req, res) => {
  try {
    const payload = JSON.stringify(req.body);
    
    // 检测Webhook类型
    const webhookType = detectWebhookType(req.headers);
    logger.info('收到Webhook请求', { type: webhookType });
    
    // 获取签名和事件类型（支持多种格式）
    let signature, event;
    
    if (webhookType === 'gitea') {
      signature = req.headers['x-gitea-signature'];
      event = req.headers['x-gitea-event'];
    } else if (webhookType === 'github') {
      signature = req.headers['x-hub-signature-256'];
      event = req.headers['x-github-event'];
    } else if (webhookType === 'gogs') {
      signature = req.headers['x-gogs-signature'];
      event = req.headers['x-gogs-event'];
    } else {
      // 兼容模式：尝试所有可能的头
      signature = req.headers['x-gitea-signature'] || 
                 req.headers['x-hub-signature-256'] ||
                 req.headers['x-gogs-signature'];
      event = req.headers['x-gitea-event'] || 
             req.headers['x-github-event'] ||
             req.headers['x-gogs-event'];
    }
    
    logger.info('Webhook详情', { 
      type: webhookType, 
      event, 
      hasSignature: !!signature,
      deliveryId: req.headers['x-gitea-delivery'] || req.headers['x-github-delivery'] || req.headers['x-gogs-delivery']
    });
    
    // 验证签名（如果配置了密钥）
    if (config.webhook.secret && signature) {
      if (!verifySignature(payload, signature, config.webhook.secret, webhookType)) {
        logger.warn('Webhook签名验证失败', { type: webhookType, signature });
        return res.status(401).json({ 
          success: false, 
          message: '签名验证失败' 
        });
      }
      logger.info('Webhook签名验证成功');
    } else if (config.webhook.secret && !signature) {
      logger.warn('配置了密钥但未收到签名');
      return res.status(401).json({ 
        success: false, 
        message: '缺少签名头' 
      });
    }
    
    // 只处理push事件
    if (event !== 'push') {
      logger.info('忽略非push事件', { event, type: webhookType });
      return res.json({ 
        success: true, 
        message: `事件 ${event} 已忽略` 
      });
    }
    
    const pushData = req.body;
    
    // 检查是否是目标分支
    const branchName = pushData.ref?.replace('refs/heads/', '');
    if (branchName !== config.git.targetBranch) {
      logger.info('忽略非目标分支推送', { 
        branch: branchName, 
        targetBranch: config.git.targetBranch,
        type: webhookType
      });
      return res.json({ 
        success: true, 
        message: `分支 ${branchName} 不是目标分支，已忽略` 
      });
    }
    
    // 获取提交信息（兼容不同格式）
    const commitInfo = pushData.head_commit || pushData.commits?.[pushData.commits.length - 1];
    const commitId = pushData.after || commitInfo?.id || 'unknown';
    const commitMessage = commitInfo?.message || '';
    const authorName = commitInfo?.author?.name || commitInfo?.author?.username || 'unknown';
    
    // 记录部署历史
    const deployRecord = {
      id: Date.now().toString(),
      timestamp: new Date().toISOString(),
      branch: branchName,
      commit: commitId,
      commitMessage: commitMessage,
      author: authorName,
      webhookType: webhookType,
      status: 'pending',
      logs: []
    };
    
    logger.info('开始部署任务', {
      deployId: deployRecord.id,
      branch: branchName,
      commit: commitId.substring(0, 8),
      author: authorName,
      type: webhookType
    });
    
    await historyService.addRecord(deployRecord);
    
    // 异步执行部署
    deployService.deploy(deployRecord.id, pushData)
      .then(result => {
        logger.info('部署完成', { 
          deployId: deployRecord.id, 
          success: result.success,
          type: webhookType
        });
      })
      .catch(error => {
        logger.error('部署失败', { 
          deployId: deployRecord.id, 
          error: error.message,
          type: webhookType
        });
      });
    
    res.json({ 
      success: true, 
      message: '部署任务已启动',
      deployId: deployRecord.id,
      webhookType: webhookType
    });
    
  } catch (error) {
    logger.error('Webhook处理错误', { 
      error: error.message,
      stack: error.stack,
      headers: req.headers,
      body: req.body ? 'present' : 'missing'
    });
    res.status(500).json({ 
      success: false, 
      message: '处理Webhook时发生错误',
      error: process.env.NODE_ENV === 'development' ? error.message : '内部服务器错误'
    });
  }
});

// 获取Webhook状态
router.get('/status', (req, res) => {
  res.json({
    success: true,
    data: {
      webhookPath: config.webhook.path,
      targetBranch: config.git.targetBranch,
      hasSecret: !!config.webhook.secret,
      supportedTypes: ['github', 'gitea', 'gogs'],
      version: '2.0.0'
    }
  });
});

// 获取支持的Webhook类型信息
router.get('/info', (req, res) => {
  res.json({
    success: true,
    data: {
      supportedWebhooks: {
        github: {
          signatureHeader: 'x-hub-signature-256',
          eventHeader: 'x-github-event',
          deliveryHeader: 'x-github-delivery',
          signatureFormat: 'sha256=<hex>'
        },
        gitea: {
          signatureHeader: 'x-gitea-signature',
          eventHeader: 'x-gitea-event',
          deliveryHeader: 'x-gitea-delivery',
          signatureFormat: '<hex>'
        },
        gogs: {
          signatureHeader: 'x-gogs-signature',
          eventHeader: 'x-gogs-event',
          deliveryHeader: 'x-gogs-delivery',
          signatureFormat: '<hex>'
        }
      },
      configuration: {
        targetBranch: config.git.targetBranch,
        hasSecret: !!config.webhook.secret,
        webhookPath: config.webhook.path
      }
    }
  });
});

module.exports = router;